package com.muchfish;

import java.sql.*;

/**
 * JDBC问题总结：
 * 1.数据库配置信息存在硬编码问题
 * 2.频繁创建和释放数据库链接
 * 3.sql语句、设置参数、获取结果集参数均存在硬编码问题
 * 4.不方便写动态sql
 *      使⽤preparedStatement向占有位符号传参数存在硬编码，因为sql语句的where条件不⼀定，可能多也可能少，修改sql还要修改代码，系统不易维护 。
 * 5.手动封装返回结果集较为繁琐
 * 解决思路：
 * 1. 将数据库配置信息抽取到xml配置⽂件中
 * 2. 使⽤数据库连接池初始化连接资源
 * 3. 将sql语句抽取到xml配置⽂件中
 * 4. 使⽤反射、内省等底层技术，⾃动将实体与表进⾏属性与字段的⾃动映射
 * ｜ 内省通常基于反射实现。
 * ｜ 内省的目的是找出 bean 的 getter 和 setter 以便操作这个 bean，
 * ｜ 所以只要看到有 getter 或者 setter 就认为这个类有那么一个字段，
 * ｜ 比如看到 getName() 内省就会认为这个类中有 name 字段，
 * ｜ 但事实上并不一定会有 name。
 */
public class JDBCExample {
    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            // 1.加载数据库驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 2.通过驱动管理类获取数据库链接
            connection =
                    DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC", "root", "123456");
            // 3.定义sql语句？表示占位符
            String sql = "select * from user where username = ?";
            // 4.获取预处理statement
            preparedStatement = connection.prepareStatement(sql);
            // 5.设置参数，第0个参数为sql语句中参数的序号(从1开始)，第1个参数为设置的参数值
            preparedStatement.setString(1, "tom");
            // 6.向数据库发出sql执⾏查询，查询出结果集
            resultSet = preparedStatement.executeQuery();
            // 7.解析结果集，封装成对象
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String username = resultSet.getString("username");
                // 封装User
                User user = new User();
                user.setId(id);
                user.setUsername(username);
                System.out.println(user);
            }
        } catch (
                Exception e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

class User {
    private Integer id;
    private String username;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                '}';
    }
}